using Microsoft.AspNetCore.Http.Json;
using Microsoft.EntityFrameworkCore;
using ProxyServer;
using ProxyServer.Acme;
using ProxyServer.AliDns;
using ProxyServer.Constants;
using ProxyServer.Endpoints;
using ProxyServer.EntityFrameworkCore;
using ProxyServer.HostedService;
using ProxyServer.Kestrel;
using ProxyServer.Quartz;
using ProxyServer.Yarp;
using Serilog;
using System.Text.Json.Serialization;
using Certs.Apis;
using ProxyServer.Certs;

var builder = WebApplication.CreateBuilder(args);

builder.Configuration
    .AddUserSecrets<Program>()
    .AddEnvironmentVariables("PROXY_")
    .AddAgileConfig(builder.Configuration);

Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration)
    .Enrich.FromLogContext()
    .CreateLogger();

var adminHosts = builder.Configuration.GetValue<string>("AdminHosts", "*:5000;*.5001").Split(";").ToArray();

Log.Logger.Information("Admin Hosts: {@Address}", adminHosts);

builder.WebHost.ConfigureKestrel(options =>
{
    options.Limits.MaxRequestBodySize = null;
});

builder.Host.UseSerilog();

builder.Services
    .AddCors()
    .AddProblemDetails()
    .AddHttpContextAccessor()
    .AddOpenApiDocument()
    .AddEndpointsApiExplorer();

builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));

builder.Services.Configure<JsonOptions>(options =>
{
    options.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
    options.SerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
    options.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
    options.SerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString;
});

builder.Services.AddReverseProxy()
    .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"))
    .LoadFromApp();

var databaseProvider = builder.Configuration.GetDatabaseProvider() ?? DatabaseProviderNames.Sqlite;
var connectionString = builder.Configuration.GetConnectionString(databaseProvider);

builder.Services.AddEntityFrameworkCore(databaseProvider, connectionString);

builder.Services
    .AddAlibabaCloud()
    .AddAcme()
    .AddQuartzServices()
    .AddCertificateServices()
    .AddAutoCertificates()
    .AddHostedServices();

builder.Services.AddAuthentication();

builder.Services.AddCertsApi();

var app = builder.Build();

await app.RegisterJobs();

app.UseSerilogRequestLogging();

if (app.Environment.IsDevelopment())
{
    app.UseOpenApi();
    app.UseSwaggerUi();
}

app.UseCors();

app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapEndpoints().ProducesProblem(500).ProducesValidationProblem().RequireHost(adminHosts);
app.MapReverseProxy();
app.MapFallbackToFile("index.html").RequireHost(adminHosts);

app.Run();
